; 2009-08-23
;   Fritz Kunze
;  A collection of useful elisp functions taken from all over the net
;

;; making windows pathnames useful in emacs
;;http://stackoverflow.com/questions/11835026/making-a-windows-path-useful-in-emacs-lisp
;;Add this to your .emacs, maybe bind it to a convenient key. 

(defun paste-windows-path (pth) (interactive "*sWindows path:") (insert (replace-regexp-in-string "\\\\" "\\\\\\\\" pth)))
(global-set-key  [f11] 'paste-windows-path)
(message "hey fritz - you can now use f-11 to paste a windows pathname into emacs")

;http://stackoverflow.com/questions/3669511/the-function-to-show-current-files-full-path-in-mini-buffer
;I need to get the full path of the file that I'm editing with emacs.
;Is there a function for that?
;If not, what would be the elisp function for getting that?
;How can I copy the result (path name) to a clipboard so that I can reuse it?

(defun copy-full-path-to-kill-ring ()
  "copy buffer's full path to kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))
(global-set-key [f2] 'copy-full-path-to-kill-ring)

(message "hey fritz - you can now use f-2 to paste the fullpathname of a file you are editing into the kill ring")


(defun resolve-sym-link ()
  "Try to resolve symbolic links into true paths. replace the string at the point with the true path."
  (interactive)
  (beginning-of-line)
  (let* ((file (buffer-substring (point)
                                 (save-excursion (end-of-line) (point))))
         (file-dir (file-name-directory file))
         (file-true-dir (file-truename file-dir))
         (file-name (file-name-nondirectory file)))
    (delete-region (point) (save-excursion (end-of-line) (point)))
    (insert (concat file-true-dir file-name))))

;;And then if I want it in the clipboard, I just kill the line (C-a C-k). But we could easily copy the truename to the clipboard in the above command, just change the last line to be:

;;(insert (kill-new (concat file-true-dir file-name)))))
;;The new part is the call to 'kill-new which puts the string in the kill ring.

(global-set-key [f1] 'resolve-sym-link)

(message "hey fritz - you can now use f-1 to get the fullpathname of a file you are editing")



;;The following file lists some of the customizations I've installed
;;file:///C:/Users/fkunze/Documents/DOCLIB/xahlee%20emacs%20tutorial/xah_emacs_tutorial/emacs/xah_emacs_init.html

;; Set up recentf so I can get a list of recent files when I start
(recentf-mode 1)

;;Question: How to show the cursor's column position?

;;Answer Alt+x column-number-mode. To always have it on, put the following code in your ~/.emacs file: (column-number-mode t).
;;;
;;; I am going to try to use emacs customizations to change the way that I deal with 
;;; column-number-mode and line-number-mode.  Uncomment the following if this fails.
;;;

;;(column-number-mode t)
;;(line-number-mode 1)

;; vim-current-buffer - does not work at the moment - fix it later

;; A simple elisp function to call vim to open and edit current buffer.

;; Instructions: Please change the path of vim/gvim to where it is on your computer. see http://www.emacswiki.org/emacs-en/vim-current-buffer

;; (defun vim-current-buffer ()
;;   (interactive)
;;   "Open current buffer file in gvim \n
;;   (let ((gvim-program "C:\Program Files (x86)\Vim\vim73\gvim.exe")
;; 	(gvim-file-name (buffer-file-name (current-buffer))))
;;     (if gvim-file-name
;; 	(progn
;; 	  (kill-buffer (current-buffer) )
;; 	  ;; need to understand the start-process and how to handle the process exit
;; 	  ;; to be implemented: when process ends, will reopen file in emacs
;; 	  (setq result (start-process "gvim" nil gvim-program gvim-file-name)))
;;       (error "Current buffer doesn't point to a file yet."))
;;     (unless result (find-file gvim-file-name))))
 
(defun get-download-string ()
"use with M-x rst-mode only (I don't understand the syntax tables
 that are used) - used to help with sphinx documentation
 references With cursor placed on a filename prefix of the form:
 xx1-xx2-...-xxn where the file name is xx1-xx2-...-xxn.pdf
 returns strings of the form (just the first two lines are shown) 
then some other strings to help build description entries:

(1)
#. :download:`xx1 xx2 ... xxn <xx1-xx2-...-xxn.pdf>` 

(2)
.. _xx1-xx2-...- xxn: ../_downloads/xx1-xx2-...-xxn.pdf

Example Use -  

(1) Make sure you are in rst-mode
(2) make sure there is text before and after the string
(3) position your cursor somewhere in:
GL001-0004-0710.pdf and execute
M-x get-download-string, and you should see:
------  Output ------
GL001-0004-0710.pdf
.. _GL001-0004-0710:

#. :download:`GL001-0004-0710 <GL001-0004-0710.pdf>` - TITLE
.. _GL001-0004-0710: ../_downloads/GL001-0004-0710.pdf
Description
   `GL001-0004-0710 google docs link < >`_
   Local Source: ``C:\pandorabots\LegalAgreements\FormRepository\GL001-0004-0710.docx``
   Google Docs Source: navigate to `link < >`_ and then execute :menuselection:`File --> Download as --> Word`.
--- End Output ----
This is my third elisp function
See http://xahlee.org/emacs/elisp_common_functions.html for other possible ways of writing this function.

"

(interactive)
(let (filename)
 (setq filename (thing-at-point 'symbol))
(progn 
  (search-forward "\n") (backward-char)
  (insert
    (concat "\n" ".. _" filename ":"))
  (insert
    (concat "\n"))
  (insert
    (concat "\n" "#. :download:`" filename " <" filename ".pdf>`" " - TITLE"))
  (insert
    (concat "\n" ".. _" filename ": ../_downloads/" filename ".pdf"))
  (insert
    (concat "\n"))
  (insert
    (concat "\n" "   " "Description"))
  (insert
    (concat "\n"))
  (insert
    (concat "\n" "   "  "`" filename " google docs link " " < >`_" ))
  (insert
    (concat "\n"))
  (insert
    (concat "\n" "   " "Local Source: " "``C:\\pandorabots\\LegalAgreements\\FormRepository\\"  filename ".docx``"))
  (insert
    (concat "\n"))
  (insert
    (concat "\n" "   " "Word file link: navigate to `" filename "source " "< >`_" " and then execute :menuselection:`File --> Download as --> Word`.")) 
)))

;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph    
;;; You can convert an entire buffer from paragraphs to lines by recording a macro that calls ‘unfill-paragraph’ and moves past the blank-line to the next unfilled paragraph and then executing that macro on the whole buffer, ‘C-u 0 C-x e’ (see InfiniteArgument (http://www.emacswiki.org/emacs/InfiniteArgument) ).


(defun unfill-paragraph ()
"Takes a multi-line paragraph and makes it into a single line of text."
 (interactive)
 (let ((fill-column (point-max)))
   (fill-paragraph nil)))

(global-set-key (kbd "M-Q") 'unfill-paragraph)
(message "from elisp_util.el: hey fritz - we've finished loading unfill-paragraph - use it with longlines-mode disabled")

;;http://stackoverflow.com/questions/5682631/what-are-good-custom-keybindings-in-emacs

;; I have an unconventional approach to this that I recommend highly. I have redefined the C-l ('ell') key to be a prefix key, and I use that to prefix my favorite commands. This key is very easy to type and it is bound to a function ('recenter) that isn't used that much.

;; Well, I don't use 'recenter much, but even if you did, it can be assigned to C-l C-l which is almost as easy to type, and a small price to pay for the possibilities opened up by the Ctrl-L-map . (Actually I prefer 'redraw-display to 'recenter, so I gave that the place of honor.)

;; I don't remember where I got the magic incantation that makes it work:

(global-unset-key "\C-l")
(defvar ctl-l-map (make-keymap)
     "Keymap for local bindings and functions, prefixed by (^L)")
(define-key global-map "\C-l" 'Control-L-prefix)
(fset 'Control-L-prefix ctl-l-map)

;; Then you can define keys to your heart's content. C-l is a great place to put bindings for your own commands, as well as functions that are not bound to keys, or are bound to keys you can't remember or find hard to type. Here are some sample bindings to standard functions:

(define-key ctl-l-map "h"  'command-history)

(define-key ctl-l-map "\C-l"  'recenter-top-bottom)
(define-key ctl-l-map "l"  'recenter)



;; (define-key ctl-l-map "g"  'goto-line)
;; (define-key ctl-l-map "r"  'replace-string)
;; (define-key ctl-l-map "R"  'replace-regexp)
;; (define-key ctl-l-map "q"  'query-replace)
;; (define-key ctl-l-map "Q"  'query-replace-regexp)
;; (define-key ctl-l-map "o"  'overwrite-mode)
;; (define-key ctl-l-map "\C-w"  'kill-rectangle)
;; (define-key ctl-l-map "\C-y"  'yank-rectangle)
;; (define-key ctl-l-map "h"  'command-history)
(define-key ctl-l-map "w"  'write-region)
;; (define-key ctl-l-map "r" 'electric-replace-string)
;; (define-key ctl-l-map "\er" 'replace-string)
;; (define-key ctl-l-map "T"  'delete-trailing-whitespace)
;; (define-key ctl-l-map "C"  'describe-char)
;; (define-key ctl-l-map "W"  'ediff-regions-wordwise)
;; (define-key ctl-l-map "L"  'ediff-regions-linewise)
;; (define-key ctl-l-map "\C-f" 'facemenu-remove-all)
;; (define-key ctl-l-map "\C-c" 'calendar)
;; (define-key ctl-l-map "m"  'not-modified)   ;; already at M-~
;; (define-key ctl-l-map "\C-q" 'fill-region)
;; (define-key ctl-l-map "u" 'set-buffer-file-coding-system)
;; (define-key ctl-l-map [?\C-2] 'transient-mark-mode)
;; (define-key ctl-l-map "\C-@"  'transient-mark-mode)
;; (define-key ctl-l-map "\C-n"  'linum-mode)
;; (define-key ctl-l-map "\C-s" 'isearch-forward-regexp)
;; (define-key ctl-l-map "\C-r" 'isearch-backward-regexp)a
;; (define-key ctl-l-map "U" 'browse-url)
;; (define-key ctl-l-map "F" 'browse-url-of-file)
;; (define-key ctl-l-map "\C-u" 'undo-only


;; end of changes

(defun remove-hard-wrap-paragraph () 
  "Replace line endings into single spaces on the current paragraph."
  (interactive) 
  (let ((fill-column 90002000)) 
    (fill-paragraph nil)))

(defun remove-hard-wrap-region (start end)
  "Replace newline chars in region by single spaces." 
  (interactive "r")
  (let ((fill-column 90002000)) 
    (fill-region start end)))

;;; formerly:
;;; (global-set-key (kbd "M-Q") 'remove-hard-wrap-paragraph)
(global-set-key (kbd "M-R") 'remove-hard-wrap-region)


;; explorer
    ;; ----------
    ;;; Windows explorer to open current file - Arun Ravindran
    
    (defun explorer ()
      "Launch the windows explorer in the current directory and selects current file"
      (interactive)
      (w32-shell-execute
       "open"
       "explorer"
       (concat "/e,/select," (convert-standard-filename buffer-file-name))))
    
    (global-set-key [f12]         'explorer)        ; F12 - Open Explorer for the current file path

(message "hey fritz - you can now use f-12 to open explorer in the directory containing the file you opened")


(defun local-url-to-file-path (localFileURL)
  "Turn a localhost file url LOCALFILEURL into OS's full path.

For example, the following url:
; On Windows Vista 8-18-2009
 C:\\Users\\fkunze\\web\\emacs\\emacs.html ; ie
 file:///C:/Users/fkunze/web/emacs/emacs.html ; firefox
 file:///C:/Users/fkunze/web/emacs/emacs.html ; google chrom
 file:///C:/Users/fkunze/web/emacs/emacs.html ; safari
 file://localhost/C:/Users/fkunze/web/emacs/emacs.html ; opera
will become
 C:/Users/fkunze/web/emacs/emacs.html"
  (let ((ff localFileURL))
    (cond
     ((string-equal system-type "windows-nt") ; Windows
      (setq ff (replace-regexp-in-string "^file://localhost/" "" ff))
      (setq ff (replace-regexp-in-string "^file:///" "" ff))
      )
     ((string-equal system-type "darwin") ; Mac
      (setq ff (replace-regexp-in-string "^file://localhost" "" ff))
      (setq ff (replace-regexp-in-string "^file://" "" ff))
      )
     )
    ff
    )
  )


(defun windows-style-path-to-unix  (fpath)
  "Turn a MS Windows style full path FPATH to unix style.
Note: This drops the drive letter.

For example:
 C:\\Users\\fkunze\\web\\emacs\\emacs.html
becomes
 /Users/fkunze/web/emacs/emacs.html"
  (setq fpath (replace-regexp-in-string "\\\\" "/" fpath t t)) ; change \ to /
  (setq fpath (replace-regexp-in-string "^C:/" "/" fpath)) ; rid of windows C drive
  )

;; I can remove the next program when a later release of emacs 23 has what is described next:
;; Note that latest Emacs CVS version has the variable save-interprogram-paste-before-kill.

;;     ** When save-interprogram-paste-before-kill' is non-nil, emacs will not clobber the the interprogram paste when something is killed in it by saving the former in the kill-ring' before the latter.

;; Until that time, I am using the functon below.  See the link: http://stackoverflow.com/questions/848936/how-to-preserve-clipboard-content-in-emacs-on-windows for more information.


(defadvice kill-new (before kill-new-push-xselection-on-kill-ring activate)
  "Before putting new kill onto the kill-ring, add the clipboard/external selection to the kill ring"
  (let ((have-paste (and interprogram-paste-function
                         (funcall interprogram-paste-function))))
    (when have-paste (push have-paste kill-ring))))



;; Insertion of a date and time stamp
 (defun insert-date-string ()
   "Insert a date string year-month-day hh:mm"
   (interactive)
   (insert 
    (format-time-string "%Y-%m-%d %R") 
    ))
;; C-c i calls insert-date-string in elisp_util.el
;; set up the key binding in keyboard.el (and not here)
;;(global-set-key (kbd "C-c i") 'insert-date-string)

;; Insertion of a signature - for certain wikis - html version
 (defun insert-signature ()
   "Insert a signature and time stamp"
   (interactive)
   (insert 
    (concat 
     "<p>--- <em><a title=\"fkunze@gmail.com\" class=\"mail JSnocheck\" href=\"mailto:fkunze@gmail.com\">fkunze@gmail.com</a> "
     (format-time-string "%Y-%m-%d %R")
     "</em></p>")))

;; Insertion of doku-wiki signature 
 (defun insert-signature1 ()
   "Insert a signature and time stamp"
   (interactive)
   (insert 
    (concat 
     "--- //<fkunze@gmail.com> " 
     (format-time-string "%Y-%m-%d %R")
     "//")))
;; C-c s calls insert-signature in elisp_util.el
;; C-c r calls insert-signature1 in elisp_util.el
;; set up the key binding in keyboard.el (and not here)
;;(global-set-key (kbd "C-c s") 'insert-signature)

;; Here is a function I found on the emacs newsgroup that I might want to try some day on two monitors.  I found it here:
;;http://groups.google.com/group/gnu.emacs.help/browse_thread/thread/01b7d4153acf6P336/deb2ba863dfdd5d9?show_docid=deb2ba863dfdd5d9

(defun MakeSixWindows () 
  (interactive) 
  (delete-other-windows) 
  (split-window-vertically) 
  (split-window-horizontally) 
  (split-window-horizontally) 
  (other-window 3) 
  (split-window-horizontally) 
  (split-window-horizontally) 
  (balance-windows) 
) 
;; Posted by: Steve Yegge at September 29, 2004 02:59 AM
;; http://sites.google.com/site/steveyegge2/my-dot-emacs-file
;; Never understood why Emacs doesn't have this function.
;;

(defun rename-file-and-buffer (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME." (interactive "sNew name: ")
  (let ((name (buffer-name))
	(filename (buffer-file-name)))
    (if (not filename)
	(message "Buffer '%s' is not visiting a file!" name)
      (if (get-buffer new-name)
	  (message "A buffer named '%s' already exists!" new-name)
	(progn 	 (rename-file name new-name 1) 	 
		 (rename-buffer new-name) 	 
		 (set-visited-file-name new-name) 	 
		 (set-buffer-modified-p nil))))))

;;
;; Never understood why Emacs doesn't have this function, either.
;;
(defun move-buffer-file (dir)
  "Moves both current buffer and file it's visiting to DIR." (interactive "DNew directory: ")
  (let* ((name (buffer-name))
	 (filename (buffer-file-name))
	 (dir
	  (if (string-match dir "\\(?:/\\|\\\\)$")
	      (substring dir 0 -1) dir))
	 (newname (concat dir "/" name)))

    (if (not filename)
	(message "Buffer '%s' is not visiting a file!" name)
      (progn 	(copy-file filename newname 1) 	
		(delete-file filename) 	
		(set-visited-file-name newname) 	
		(set-buffer-modified-p nil) t)))) 







